package com.menghao.rpc.consumer.discovery;

import com.menghao.rpc.RpcConstants;
import com.menghao.rpc.consumer.handle.ReferenceAgent;
import com.menghao.rpc.zookeeper.ChildChangeListener;
import com.menghao.rpc.zookeeper.CuratorClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>对于 @Reference代理所需信息的初始化.</br>
 * <p>需要根据契约及实现找到服务提供方机器信息</p>
 *
 * @author MarvelCode
 */
public class ProviderDiscovery {

    private final static Logger LOG = LoggerFactory.getLogger(ProviderDiscovery.class);

    private CuratorClient curatorClient;

    public ProviderDiscovery(CuratorClient curatorClient) {
        this.curatorClient = curatorClient;
    }

    public void initReferenceAgent(ReferenceAgent referenceAgent) {
        detect(referenceAgent);
    }

    private void detect(final ReferenceAgent referenceAgent) {
        // 服务信息节点路径
        final String nodePath = "/" + referenceAgent.getContract() + ":" + referenceAgent.getImplCode();
        LOG.info(RpcConstants.LOG_RPC_PREFIX + "look up zookeeper node {}", nodePath);
        try {
            // 监听 ZK节点
            curatorClient.addPathListener(nodePath, (path, data) -> {
                try {
                    referenceAgent.setProviderHosts(curatorClient.getChildren(nodePath));
                } catch (Exception e) {
                    LOG.error(RpcConstants.LOG_RPC_PREFIX + "getChildren path {} exception,", nodePath, e);
                }
            });
            // 设置服务机器信息列表
            referenceAgent.setProviderHosts(curatorClient.getChildren(nodePath));
        } catch (Exception e) {
            LOG.error(RpcConstants.LOG_RPC_PREFIX +"zookeeper getNode child {} exception", nodePath, e);
        }
    }
}
